<?php
/* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4 foldmethod=marker: */

/**
 * PEAR::Services_IMDB
 *
 * Services_IMDB searches for given locations and retrieves current
 * IMDB data and, dependant on the used service, also forecasts. Up to
 * now, SOAP services from CapeScience and EJSE, XML from IMDB.com and
 * METAR/TAF from noaa.gov are supported, further services will get
 * included, if they become available and are properly documented.
 *
 * PHP versions 4 and 5
 *
 * <LICENSE>
 * Copyright (c) 2005-2007, Kevin van Zonneveld
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * o Redistributions of source code must retain the above copyright notice,
 *   this list of conditions and the following disclaimer.
 * o Redistributions in binary form must reproduce the above copyright notice,
 *   this list of conditions and the following disclaimer in the documentation
 *   and/or other materials provided with the distribution.
 * o Neither the name of the software nor the names of its contributors
 *   may be used to endorse or promote products derived from this software
 *   without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 * POSSIBILITY OF SUCH DAMAGE.
 * </LICENSE>
 *
 * @category    Web Services
 * @package     Services_IMDB
 * @author      kvz <kevin@vanzonnveld.net>
 * @copyright   2005-2007 Kevin van Zonneveld
 * @license     http://www.opensource.org/licenses/bsd-license.php  BSD License
 * @version     CVS: $Id: IMDB.php,v 1.45 2007/04/16 10:36:05 eru Exp $
 * @link        http://pear.php.net/package/Services_IMDB
 * @filesource
 */

// +----------------------------------------------------------------------+
// | PHP Version 4                                                        |
// +----------------------------------------------------------------------+
// | Copyright (c) 1997-2002 The PHP Group                                |
// +----------------------------------------------------------------------+
// | This source file is subject to version 2.0 of the PHP license,       |
// | that is bundled with this package in the file LICENSE, and is        |
// | available at through the world-wide-web at                           |
// | http://www.php.net/license/2_02.txt.                                 |
// | If you did not receive a copy of the PHP license and are unable to   |
// | obtain it through the world-wide-web, please send a note to          |
// | license@php.net so we can mail you a copy immediately.               |
// +----------------------------------------------------------------------+
// | Authors: Stephan Schmidt <schst@php-tools.net>                       |
// +----------------------------------------------------------------------+
//
//    $Id: IMDB.php,v 0.1 2007/02/01 00:10:00 kvz Exp $


/**
 * Services_IMDB
 *
 * This class acts as an interface to the Internet Movie Database webservice at http://www.imdb.com
 *
 * www.imdb.com is the largest resource for movieinformation. Information like
 * plotoutline, coverart, director, cast, can be found on virtually any movie
 * ever made.
 *
 * Services_IMDB simplifies retrieving
 * - imdb_url
 * - coverpic
 * - user rating
 * - cast
 * - director
 * - tagline
 * - plot outline
 * - genre
 * - playtime
 * of any movie.
 *
 * @category    Validate
 * @package     Services_IMDB
 * @author      Kevin van Zonneveld <kevin@vanzonneveld.net>
 * @copyright   1997-2005 Stefan Neufeind
 * @license     http://www.opensource.org/licenses/bsd-license.php  new BSD
 * @version     0.1
 */


class Services_IMDB
{
    var $allowed_keys     = array();

    function Services_IMDB()
    {
    	// constructor
    	$this->allowed_keys = array(
    		"directed_by",
    		"writing_credits",
    		"genre",
    		"tagline",
    		"plot_outline",
    		"user_rating",
    		"cast_overview_first_billed_only",
    		"also_known_as",
    		"mpaa",
    		"runtime",
			"country",
			"language",
			"color",
			"sound_mix",
			"certification",
			"trivia",
			"goofs",
			"quotes",
			"awards"
		);
    }

    function _curl_setopt_array( &$ch, $opt )
    {
        foreach( $opt as $k=>$v )  {
            curl_setopt( $ch,$k,$v );
        }
    }

    function _download( $url )
    {
        $mainversion= reset( explode( ".",phpversion() ) );
        list ( $url,$params )  = explode( "?",$url );

        $ch = curl_init();
        $opt = array(
                   CURLOPT_URL=>$url,
                   CURLOPT_HEADER=>0,
                   CURLOPT_USERAGENT=>$_SERVER[ 'HTTP_USER_AGENT' ],
                   CURLOPT_RETURNTRANSFER=>1,
                   CURLOPT_POSTFIELDS=>$params
               );

        $this->_curl_setopt_array( $ch,$opt );

        $data = curl_exec( $ch );
        $info = curl_getinfo( $ch );
        curl_close( $ch );

        return array( $info[ "http_code" ],$info[ "url" ],$data );
    }

    function imdbsearch( $moviename, &$error )
    {
        $url = "http://us.imdb.com/find?q=".urlencode( $moviename );
        list( $httpcode, $lasturl, $body )  = $this->_download( $url );

        if( $httpcode!=200 )  {
            $error = "Cannot fetch $moviename ($url), http code = $httpcode";
            return false;
        }

        if( !substr_count( strtolower( $body ),"usercomments" )  || !substr_count( strtolower( $body ),"genre" )  )  {
            $buf = strip_tags( utf8_decode( html_entity_decode( $body,ENT_QUOTES ) ),"<a>,<b>" );
            $buf = substr( $buf,strpos( strtolower( $buf ),strtolower( "following results:" ) )  +strlen( "following results:" ),strlen( $buf ) );
            preg_match( "/<a.*href=\"([^\"]+)/i", $buf, $match);
            $url = "http://us.imdb.com".$match[1];

            list( $httpcode,$lasturl,$body )  = $this->_download( $url );

            if( $httpcode!=200 )  {
                $error = "Cannot fetch $moviename ($url), http code = $httpcode";
                return false;
            }
        }

        if( substr( $lasturl,-1,1 ) !="/" )
            $lasturl.="/";

        return $lasturl;
    }

    function imdbparse( $movieurl, &$error )
    {
        $info=array();

        // download the moviepage
        list( $httpcode,$lasturl,$body )  = $this->_download( $movieurl );
        if( $httpcode!=200 )  {
            $error = "Cannot fetch $movieurl, http code = $httpcode";
            return false;
        }



		// save the coverpic before stripping all attributes
        preg_match( "/<div class=\"photo\">.*src=\"([^\"]+?)\"/isU", $body, $match);
        $info["coverpic"] = $match[1];
        $info["imdb_url"] = $lasturl;

        // throw away everything before the H1 tag
		$body = preg_replace( "/(.*)(<h1)/isU", '$2', utf8_decode(html_entity_decode($body,ENT_QUOTES)) );

        // releave all html tags of their attributes
        $body = preg_replace( "/(<\w+)(\s+.*)(>)/isU", '$1$3', $body );

        // save the imdb title of this movie
        preg_match( "/<h1>(.*)<\/h1>/isU", $body, $match);
        $info["imdbtitle"] = trim(strip_tags($match[1]));

        // cleanup tiny discrepancies caused by imdb layout changes, a little dirty currently
        $body = str_replace( "h5>","b>", $body );
        $body = str_replace( "/div>","br>", $body );
        $body = str_replace( "br/>","br>", $body );
        $body = preg_replace( "/<\/b>\s*<br>/isU", '</b>', $body );
        $body = str_replace( "<img><small>(","<b>", $body );
        $body = str_replace( ")</small><div>","</b>", $body );

        // parse everything into raw arrays
        preg_match_all( "/<b>\s*(.+)\s*<\/b>\s*(.+)\s*<br>\n/isU", $body, $matches );

        // build a clean array
        foreach($matches[1] as $i=>$key_raw){
        	// general setup & cleanup of keys
        	$key = strtolower(trim(strip_tags($key_raw)));
        	$key = str_replace(" ","_",$key);
        	$key = str_replace(array(":",","),"",$key);

        	// skip garbage keys that are not in the allowed list
        	if(!in_array($key ,$this->allowed_keys))continue;

        	// general setup & cleanup of values
        	$val_raw = $matches[2][$i];
        	$val_raw = str_replace(array("(more)","(view trailer)"),"",$val_raw);
        	$val = trim(strip_tags($val_raw));
        	$val = preg_replace( "/(\s)*\s/isU", ' ', $val );

        	// fine-tuning for some specific keys
        	switch(strtolower($key)){
        		case "cast_overview_first_billed_only":
        			$key = "cast_overview";
        			$val = strip_tags($val_raw,"<td>");
        			$val = str_replace("</td>","",$val);
        			$val = str_replace("<td>","|",$val);
        			$val = str_replace(" ... |","",$val);

        			$c = explode("||",$val);
        			foreach($c as $l){
        				$p = explode("|",$l);
						if($p[0] && $p[1]){
							$v[trim($p[0])]=trim($p[1]);
						}
        			}
        			$val = $v;
        		break;
        	}
        	// save final data
        	if($key && $val){
        		$info[$key] = $val;
        	}
        }

        return $info;
    }

    function getinfo( $moviename, &$werror )
    {
        if( $url = $this->imdbsearch( $moviename,$error ) )  {
            if( $info = $this->imdbparse( $url,$error ) )  {
                return $info;
            } else {
                $werror = "an error occured while trying to parse the imdb page: ".$error;
                return false;
            }
        } else {
            $werror = "an error occured while trying to retrieve the imdb link: ".$error;
            return false;
        }
    }
}
?>
